home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 11 / develop 11 code / The NetWork Project / NetWork Programmer's Stuff / SchedulerUnit.p < prev   
Encoding:
Text File  |  1992-07-15  |  14.7 KB  |  409 lines  |  [TEXT/MPS ]

  1. Unit SchedulerUnit;
  2. { Copyright The NetWork Project, StatLab Heidelberg 1989-1991
  3.   Copyright G. Sawitzki, StatLab Heidelberg 1989-1991}
  4. {------------------
  5. use:    
  6. the generic scheduler for asynchronous iterations.
  7. You have to create a scheduler with New(Scheduler)
  8. and to initialize it with Scheduler.Init.
  9.  
  10. For a compute server (slave) you have to customize
  11. Msgusable and MsgEvaluation of the TaskHandler,
  12. create a TaskHandler, and install it using
  13. Scheduler.InitTaskHandler.
  14.  
  15. For a compute client (master) you have to prepare a 
  16. receiver, you have to customize NewTask of the 
  17. TaskGenerator, create a TaskGenerator, and install it 
  18. using Scheduler.InitTaskGenerator.
  19.  
  20. updating history:
  21. 1.1-0B    renamed .inc to .inc.p
  22. 1.1-0A    name changes, UNIV pointers, var messages
  23. 1.1-09    additional checks added
  24. 1.1-08  clean up
  25. 1.1-07  dynamic buffer handling
  26. 1.1-06  event-based
  27. 1.1-05    added USES NetWorkLookup
  28. 1.1-04     removed default message. 
  29.         cohandlers introduced.
  30. -------------------}
  31.  
  32. Interface
  33.  
  34.     USES
  35.         Types, ObjIntf, Errors,    Memory,
  36.         NetWork, NetWorkLookup;
  37.  
  38.     
  39. {$Setc Debugging=false}        {set true to have additional debugging information, using MacsBug}
  40. {$Setc MemberKludge=true}    {the member function of MPW 3.2 may run into a bus error instead
  41.                             of reporting false when the first argument is not an object. If
  42.                             MemberKludge is true, special cautions are taken to avoid this
  43.                             problem. If the environment is tested, set MemberKludge=false.}
  44. {$Setc paranoia=true}        {test for conditions which simply should not happen. If message 
  45.                             management is done by the scheduler and the environment is tested,
  46.                             set paranoia=false.}
  47.  
  48. const 
  49.  
  50.     {these are capability/message type flags. Move to global ??}
  51.     {bit 0..15 are used by the scheduler, bits 16..31 by the message system.}
  52.     
  53.     
  54.     {••••••• these are  n o t  the final codes •••••••}
  55.     {••••••• a l l  flags are reserved         •••••••}
  56.     {warning: the compiler does not know about hex numbers and may use
  57.     a sign extension}
  58.     {scheduler verbs}
  59.     
  60.     cAnyCapas        =            0;    {no known capabilities/no special capabilities required}
  61.     cMsgReply        =    $00008000;     {message is a reply}
  62.     cMsgNAttention    =    $00004000;    {special attention, eg. message starts a new context,
  63.                                     contains a warning etc. May be delivered with priority
  64.                                     by the message system. overrides context stamp information.}
  65.     
  66.     {message system flags}
  67.     
  68.     cUnknownFormat    =    $00010000;    {reserved to mark future format extensions}
  69.     cMustBeLaunched    =    $80000000;    {recipient must be launched. Don't lauch}
  70.  
  71.     cNilError=memFullErr ;    {nil error. ••••••• these are  n o t  the final codes •••••••}
  72.  
  73.     
  74.     {====================================================================================}
  75.  
  76. Type MessagePtr=MsgPtr;        {we use the same data type as the message sytem,
  77.                             but we don't want to mix up with the communication
  78.                             system}
  79.  
  80.     
  81.     {====================================================================================}
  82.     {low level routines, interfacing to message system. Messages are delt with
  83.     by message handlers. Typically, ther will be mesage handlers handling incoming
  84.     tasks, and those generating tasks going out.}
  85.  
  86.  
  87.     {---------------------------------------------------------------}
  88.     {    This is an abstract handler which will never be created.
  89.     It is here to define default capabilities and calling convetions
  90.     of message handlers.    }
  91.  
  92. Type tMessageHandler=object(tObject)
  93. {$IFC MemberKludge}
  94.         MemberKludgeMagic:    longint;    
  95.                             {a magic word spelling longint('tMHd') with tMessageHandlers.
  96.                             May be used to avoid bus errors caused be the MPW 3.2
  97.                             implementation of member if the first argument is not an
  98.                             object}
  99. {$ENDC}
  100.         ContextStamp:longint;    
  101.                             {a 32bit flag to verify context continuity. 0:neutral. 
  102.                             To be matched with MsgReference in the MsgRec. This flag 
  103.                             is specific to a message handler. Multiple concurrent
  104.                             message handlers may have differing context stamps.}    
  105.  
  106.         NrPendingMessages:longint;
  107.                             {number of pending messages for this message handler. Do not
  108.                             free the message handler unless NrPendingMessages is zero}
  109.  
  110.         {--------- standard methods             ------------------------------------ }
  111.  
  112.         procedure tMessageHandler.init;            
  113.                               {once only initialization. Set NrPendingMessages to zero and
  114.                             calls restart.}
  115.         
  116.         procedure tMessageHandler.restart;    {use this for a first start of the 
  117.                             message handler within a context. Set a new ContextStamp.}
  118.  
  119.         {--------- message handling ------------------------------------------------ }
  120.  
  121.         procedure tMessageHandler.Stamp(Msg:MsgPtr);
  122.                             {Set identificator fields in msg record. Should set
  123.                             MsgUserRefCon to longint(self).
  124.                             Increases NrPendingMessages by one.}
  125.                             
  126.         function tMessageHandler.DisposMsg(var Msg:MsgPtr):OsErr;
  127.                             {Release Msg and all buffers associated with Msg.
  128.                             Reduce NrPendingMessages by one.}
  129.  
  130.         {--------- low level buffer and message handling ---------------------------- }
  131.     
  132.         function tMessageHandler.NewPrioPtr(var PrioSize:longint):ptr;
  133.                             {Allocate a new buffer for priority data. 
  134.                             Entry: PrioSize=Requested size;
  135.                             Exit: PrioSize=Allocated size;}
  136.                             
  137.         function tMessageHandler.NewCorePtr(var CoreSize:longint):ptr;
  138.                             {Allocate a new buffer for core data. 
  139.                             Entry: PrioSize=Requested size;
  140.                             Exit: PrioSize=Allocated size;}
  141.  
  142.         procedure tMessageHandler.DisposPrioPtr(var PrioPtr:UNIV Ptr);
  143.                             {Dispose  buffer for priority data.}
  144.                             
  145.         procedure tMessageHandler.DisposCorePtr(var CorePtr:UNIV Ptr);
  146.                             {Dispose buffer for core data.}
  147.  
  148.         function tMessageHandler.Destroy(var Msg:MsgPtr):OsErr;
  149.                             {Destroy the message record, and set Msg to nil.
  150.                             Decreases NrPendingMessages by one, but does not dispose buffers.}
  151.                             
  152.     end;
  153.  
  154.  
  155.     {====================================================================================}
  156.     {These handlers are called by the scheduler. They inherit the fields of
  157.     the default message handler and add their own extensions. }
  158.  
  159.  
  160.     {The TaskHandler may be used by both compute servers and compute clients.}
  161.  
  162. Type tTaskHandler=object(tMessageHandler)
  163.  
  164.         {--------- working space for Msgusable ---------------------------- }
  165.             
  166.         
  167.                             {"Master" address is PrivilegedAddr. 
  168.                             If PrivilegedTimeout is not 
  169.                             zero, and master is not timed out, only 
  170.                             messages from this origin will be accepted}
  171.  
  172.         PrivilegedInterval:    longint;    
  173.                             {timeout interval for master. approximate 
  174.                             lifetime of faithfulness to PrivilegedAddr}
  175.                             
  176.         PrivilegedTimeout:    longint;                    
  177.                             {next timeout point
  178.                             =last encounter+PrivilegedInterval
  179.                             0: no privileged defined}
  180.         
  181.         PrivilegedAddr:        MsgAddr;
  182.                             {address of privileged user. valid if
  183.                             PrivilegedTimeout≠0}
  184.                             
  185.         usableCapas:        longint;
  186.         
  187.  
  188.         {--------- standard methods             ------------------------------------ }
  189.  
  190.         procedure tTaskHandler.init;    override;        
  191.                               {once only initialization. will be called by
  192.                             the scheduler on installation.}
  193.         procedure tTaskHandler.restart;override;
  194.                             {restart the receiver. Sets ContextStamp to a neutral identifier.}
  195.                             
  196.                                                         
  197.         {--------- problem specific methods    ------------------------------------ }
  198.         
  199.         
  200.         
  201.         function tTaskHandler.MsgHeaderusable(var msg:MsgPtr):boolean;
  202.                             {--------- This function may be customized  -------------------------}
  203.                             {check incoming message whether it is in context. This procedure should
  204.                             filter out all stray messages which may result from multiple users
  205.                             of the network communication system.
  206.                             The default does a pre-check of the master, and updates the master 
  207.                             info if appropriate. 
  208.         
  209.                             Customization should verify the context word as well.
  210.                             Returns true if the message is acceptable for further processing.}
  211.  
  212.         function tTaskHandler.MsgUsable(var msg:MsgPtr):boolean;
  213.                             {--------- This function may be customized  -------------------------}
  214.                             {check incoming message whether it is usable. Will be called after the
  215.                             context has beeen checked. This procedure should
  216.                             filter out all outdated messages.}
  217.         
  218.         
  219.         procedure tTaskHandler.MsgEvaluation(var msg:MsgPtr);
  220.                             {--------- This function must be customized -------------------------}
  221.                             {evaluate information. Do not generate new task as a response.}
  222.     end;
  223.  
  224.  
  225.  
  226.     {====================================================================================}
  227.  
  228.     {The TaskGenerator will be used only by compute clients.}
  229.  
  230. Type tTaskGenerator=object(tMessageHandler)
  231.  
  232.         {--------- timing information for scheduler    ----------------------------- }
  233.  
  234.         WaitInterval:longint;    {approximate interval to wait before new task}
  235.         TickleInterval:longint;    {approximate interval for trying for a new 
  236.                                 random partner approximately (in ticks)}
  237.  
  238.  
  239.  
  240.         {--------- working space for NewMsg ---------------------------- }
  241.             
  242.                 
  243.         DefaultCapasVerb:    longint;
  244.                             {Defaults for CapasVerb}
  245.  
  246.         {--------- standard methods             ------------------------------------ }
  247.  
  248.         procedure tTaskGenerator.init;override;
  249.                                 {once only initialization. will be called by the 
  250.                                 scheduler on installation.}
  251.         
  252.         procedure tTaskGenerator.restart;override;
  253.                                 {Restart for a new context. Sets ContextStamp to a  
  254.                                 new random identifier. }
  255.     
  256.         procedure tTaskGenerator.Stamp(Msg:MsgPtr); override;
  257.                                 {Set MsgReference to a unique identifier.}
  258.                             
  259.         {--------- This function must be customized  -------------------------}
  260.         function tTaskGenerator.NewTask(var Msg:MsgPtr):boolean;
  261.                                 {If a new message can be defined, set up buffers,
  262.                                 adjust the fields of Msg^ as appropriate, stamp the
  263.                                 message and return true. If no new message
  264.                                 should be defined, return false}
  265.         
  266.     end;
  267.  
  268.     {====================================================================================}
  269.  
  270.  
  271.     {---------------------------------------------------------------}
  272.     {    Cohandler    
  273.     This is a courtesy entry to allow experiments with smart schedulers
  274.     dynamically without changing the Scheduler itself. It may run its 
  275.     statistics on incoming tasks, and adapt the TaskGenerator's iterations
  276.     and task id as appropriate.}
  277.  
  278. Type tSchedulerPhase=(pUndefined,pUsable,pUnUsable,
  279.     pStartNewTask,pNewTaskDone,pNoNewTask,pSendMessage,pReplyMessage,
  280.     pHousekeepingDestroy,pInit,pFree,
  281.     pAcceptMsg);
  282.  
  283. Type tSchedulerCohandler=object(tObject)
  284.         procedure tSchedulerCohandler.CoHandle(cmd:tSchedulerPhase;msg:MsgPtr);
  285.         
  286.         procedure tSchedulerCohandler.reset;
  287.     end;
  288.  
  289.     {====================================================================================}
  290. Type
  291.     tScheduler=object(tObject)
  292.  
  293.         MySelf:MsgAddr;                        {the address and type this scheduler is installed at}
  294.         MyTransport:TransportPtr;            {the transport system corresponding to this address}    
  295.         
  296.         receiving:boolean;                    {receiving is supported place receiving is true. 
  297.                                             A TaskHandler must be installed}
  298.                                             
  299.         sending:boolean;                    {TaskGeneration and sending is supported 
  300.                                             if sending is true.A TaskGenerator must be 
  301.                                             installed.
  302.                                             Reply-Messages does not require sending to 
  303.                                             be active.}
  304.                                             
  305.         {--------- cohandler to allow for experimental implementations      --------- } 
  306.         
  307.                 CoHandler:tSchedulerCohandler;        {for experimental use}
  308.                 
  309.         {--------- working space for Cohandler   ------------------------------------ }
  310.         {Scheduler and cohandler may fill these entries with proposals. NewTask is free to
  311.         use or neglect them. However to allow for adaptive schedulers, NewTask should 
  312.         note its choices here. }
  313.  
  314.         TaskAddr:        MsgAddr;            {the effective address of the task server}
  315.         TaskId:            longint;            {a stamp to identify the task.}
  316.         TaskIterations:    longint;            {the number of elementary actions to perform}
  317.  
  318.         {--------- schedulers information about the receiver and its world --------- }
  319.  
  320.         TaskHandler:    tTaskHandler;    {will be called whenever a packet comes in}
  321.  
  322.         {--------- schedulers information about the TaskGenerator and its world ---- }
  323.  
  324.         TaskGenerator:    tTaskGenerator;        {will be called whenever scheduler wants to send a packet}
  325.         NextTickle:        Longint;            {next time to make a try call}
  326.         NextWait:        Longint;            {do not call before this time}
  327.         PrevDest:        MsgAddr;            {the last destination a task was sent to}
  328.  
  329.         {--------- error latch--------------- ------------------------------------ }
  330.  
  331.         Err:            OsErr;                {latch error code here to allow for silent implementations}
  332.         ErrQuiet:        Boolean;            {no error reporting}
  333.         ErrFrom:        tSchedulerPhase;
  334.         procedure tScheduler.handleError(from:tSchedulerPhase;which:OsErr);
  335.                                 {errors during Scheduler activity.
  336.                                             should be customized.}
  337.  
  338.         {--------- main control of scheduler -------------------------------------- }
  339.         
  340.         procedure tScheduler.init;                    {the once-only initialization}
  341.  
  342.         procedure tScheduler.reset;                    {reset to no error, not sending, not receiving.}
  343.  
  344.         procedure tScheduler.free; override;
  345.         
  346.         procedure tScheduler.setSending(onoff:boolean);
  347.         procedure tScheduler.setReceiving(onoff:boolean);
  348.  
  349.         {--------- installation of handlers -------------------------------------- }
  350.  
  351.         Procedure tScheduler.InitTaskHandler(newTaskHandler:tTaskHandler);
  352.  
  353.         Procedure tScheduler.InitTaskGenerator(newTaskGenerator:tTaskGenerator);
  354.  
  355.  
  356.         {---------  schedulers task routine -------------------------------------- }
  357.  
  358.         procedure tScheduler.HandleMsg (Msg : MsgPtr);
  359.                             {take a message and handle it. The appropriate action is
  360.                             determined by the message staus and action code.}
  361.  
  362.         procedure tScheduler.PeriodicTask;
  363.                             {the periodic task. should be called from the event loop.
  364.                             Performs housekeeeping actions.}
  365.     
  366.         function tScheduler.GetSleep: longint;
  367.                             { returns the delay until the next activation, in ticks}
  368.                             
  369.         {---------  schedulers kickOff      -------------------------------------- }
  370.         procedure tScheduler.kickOff(maxcount,maxticks:integer);
  371.                             {initiates a round of at most maxcount scheduler 
  372.                             tasks for a total time of maxticks (whatever comes
  373.                             first). The usual send interval limitations do not
  374.                             apply during kick off}
  375.  
  376.         {---------  internal routines. put here to allow easy customization ------ }
  377.         procedure tScheduler.DoNewTask(addr:MsgAddr;Transport:TransportPtr);
  378.                             {call NewTask, with all support, for addr}
  379.                             
  380.         procedure tScheduler.sendmessage(msg:MessagePtr);
  381.                             {send the message indicated by msg, and note in
  382.                             schedulers queue.}
  383.                             
  384.         procedure tScheduler.replymessage(msg:MessagePtr;flagsToAdd:longint);
  385.                             {send the message indicated by msg, but to msg
  386.                             target}
  387.     
  388.  
  389.     end;
  390.  
  391.  
  392. var
  393.     NetWorkScheduler:tScheduler;
  394.  
  395.  
  396.     {====================================================================================}
  397.  
  398.  
  399.     Implementation 
  400. {------------------------------------------------------------}
  401.  
  402. const 
  403.     unitversion='1.1-0B';
  404.     unitId='SchedulerUnit';
  405.  
  406.     {$I SchedulerUnit.inc.p}
  407.  
  408. end. { SchedulerUnit unit }
  409.